const { prisma } = require('../config/prisma');

class LocalServicePrisma {
  constructor(data) {
    this.id = data.id;
    this.user_id = data.user_id;
    this.category_id = data.category_id;
    this.title = data.title;
    this.province = data.province;
    this.city = data.city;
    this.basic_services = data.basic_services;
    this.extended_services = data.extended_services;
    this.after_sale_service = data.after_sale_service;
    this.contact_info = data.contact_info;
    this.images = data.images;
    this.status = data.status;
    this.audit_status = data.audit_status;
    this.audit_comment = data.audit_comment;
    this.audit_time = data.audit_time;
    this.auto_publish_at = data.auto_publish_at;
    this.deposit_required = data.deposit_required;
    this.deposit_paid = data.deposit_paid;
    this.view_count = data.view_count;
    this.like_count = data.like_count;
    this.comment_count = data.comment_count;
    this.created_at = data.created_at;
    this.updated_at = data.updated_at;
    
    // 关联数据
    this.user = data.users;
    this.category = data.service_categories;
  }

  /**
   * 根据用户ID查找服务列表
   * @param {BigInt} userId 用户ID
   * @param {Object} options 查询选项
   * @returns {Promise<{services: LocalServicePrisma[], total: number}>}
   */
  static async findByUserId(userId, options = {}) {
    const {
      page = 1,
      limit = 10,
      status = null,
      audit_status = null
    } = options;

    const where = {
      user_id: BigInt(userId)
    };

    if (status) {
      where.status = status;
    }
    if (audit_status) {
      where.audit_status = audit_status;
    }

    const [services, total] = await Promise.all([
      prisma.local_services.findMany({
        where,
        include: {
          users: true,
          service_categories: true
        },
        orderBy: { created_at: 'desc' },
        skip: (page - 1) * limit,
        take: limit
      }),
      prisma.local_services.count({ where })
    ]);

    return {
      services: services.map(service => new LocalServicePrisma(service)),
      total
    };
  }

  /**
   * 根据分类和位置搜索服务
   * @param {Object} searchParams 搜索参数
   * @returns {Promise<{services: LocalServicePrisma[], total: number}>}
   */
  static async search(searchParams = {}) {
    const {
      category_id = null,
      province = null,
      city = null,
      page = 1,
      limit = 10,
      keyword = null
    } = searchParams;

    const where = {
      status: 'PUBLISHED',
      audit_status: 'APPROVED'
    };

    if (category_id) {
      where.category_id = Number(category_id);
    }
    if (province) {
      where.province = province;
    }
    if (city) {
      where.city = city;
    }
    if (keyword) {
      where.OR = [
        { title: { contains: keyword } },
        { basic_services: { contains: keyword } },
        { extended_services: { contains: keyword } }
      ];
    }

    const [services, total] = await Promise.all([
      prisma.local_services.findMany({
        where,
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true
            }
          },
          service_categories: true
        },
        orderBy: { created_at: 'desc' },
        skip: (page - 1) * limit,
        take: limit
      }),
      prisma.local_services.count({ where })
    ]);

    return {
      services: services.map(service => new LocalServicePrisma(service)),
      total
    };
  }

  /**
   * 根据ID查找服务
   * @param {BigInt} id 服务ID
   * @param {Object} options 查询选项
   * @returns {Promise<LocalServicePrisma|null>}
   */
  static async findById(id, options = {}) {
    if (id === null || id === undefined) {
      return null;
    }

    const { includeUser = false, includeCategory = false } = options;
    const include = {};
    
    if (includeUser) {
      include.users = {
        select: {
          id: true,
          nickname: true,
          avatar_url: true,
          phone_number: true,
          wechat_id: true
        }
      };
    }
    if (includeCategory) {
      include.service_categories = true;
    }

    const service = await prisma.local_services.findUnique({
      where: { id: BigInt(id) },
      include: Object.keys(include).length > 0 ? include : undefined
    });

    return service ? new LocalServicePrisma(service) : null;
  }

  /**
   * 创建新的本地服务
   * @param {Object} data 服务数据
   * @returns {Promise<LocalServicePrisma>}
   */
  static async create(data) {
    const service = await prisma.local_services.create({
      data: {
        user_id: BigInt(data.user_id),
        category_id: Number(data.category_id),
        title: data.title,
        province: data.province,
        city: data.city,
        basic_services: data.basic_services,
        extended_services: data.extended_services,
        after_sale_service: data.after_sale_service,
        contact_info: data.contact_info,
        images: data.images ? JSON.stringify(data.images) : null,
        status: data.status || 'DRAFT',
        audit_status: 'PENDING',
        auto_publish_at: data.auto_publish_at || null,
        deposit_required: data.deposit_required || 0
      },
      include: {
        users: true,
        service_categories: true
      }
    });
    return new LocalServicePrisma(service);
  }

  /**
   * 更新服务信息
   * @param {Object} data 更新数据
   * @returns {Promise<LocalServicePrisma>}
   */
  async update(data) {
    const updateData = {};
    
    if (data.title !== undefined) updateData.title = data.title;
    if (data.province !== undefined) updateData.province = data.province;
    if (data.city !== undefined) updateData.city = data.city;
    if (data.basic_services !== undefined) updateData.basic_services = data.basic_services;
    if (data.extended_services !== undefined) updateData.extended_services = data.extended_services;
    if (data.after_sale_service !== undefined) updateData.after_sale_service = data.after_sale_service;
    if (data.contact_info !== undefined) updateData.contact_info = data.contact_info;
    if (data.images !== undefined) updateData.images = data.images ? JSON.stringify(data.images) : null;
    if (data.status !== undefined) updateData.status = data.status;
    if (data.deposit_required !== undefined) updateData.deposit_required = data.deposit_required;
    
    // 审核相关字段
    if (data.audit_status !== undefined) updateData.audit_status = data.audit_status;
    if (data.audit_comment !== undefined) updateData.audit_comment = data.audit_comment;
    if (data.audit_time !== undefined) updateData.audit_time = data.audit_time;
    if (data.auto_publish_at !== undefined) updateData.auto_publish_at = data.auto_publish_at;
    
    updateData.updated_at = new Date();

    const updatedService = await prisma.local_services.update({
      where: { id: BigInt(this.id) },
      data: updateData,
      include: {
        users: true,
        service_categories: true
      }
    });

    Object.assign(this, updatedService);
    return this;
  }

  /**
   * 审核服务
   * @param {string} auditStatus 审核状态 (APPROVED|REJECTED)
   * @param {string} comment 审核意见
   * @returns {Promise<LocalServicePrisma>}
   */
  async audit(auditStatus, comment = null) {
    return await this.update({
      audit_status: auditStatus,
      audit_comment: comment,
      audit_time: new Date()
    });
  }

  /**
   * 发布服务
   * @returns {Promise<LocalServicePrisma>}
   */
  async publish() {
    if (this.audit_status !== 'APPROVED') {
      throw new Error('服务未通过审核，无法发布');
    }
    return await this.update({ status: 'PUBLISHED' });
  }

  /**
   * 下架服务
   * @returns {Promise<LocalServicePrisma>}
   */
  async offline() {
    return await this.update({ status: 'OFFLINE' });
  }

  /**
   * 硬删除服务（从数据库中完全删除）
   * @returns {Promise<void>}
   */
  async hardDelete() {
    await prisma.local_services.delete({
      where: { id: BigInt(this.id) }
    });
  }

  /**
   * 设置自动发布时间
   * @param {Date} publishTime 自动发布时间
   * @returns {Promise<LocalServicePrisma>}
   */
  async setAutoPublish(publishTime) {
    return await this.update({
      auto_publish_at: publishTime
    });
  }

  /**
   * 自动发布过期的服务
   * @returns {Promise<number>} 发布的服务数量
   */
  static async autoPublishExpired() {
    const now = new Date();
    
    // 查找需要自动发布的服务
    const expiredServices = await prisma.local_services.findMany({
      where: {
        status: 'DRAFT',
        audit_status: 'PENDING',
        auto_publish_at: {
          lte: now
        }
      }
    });

    if (expiredServices.length === 0) {
      return 0;
    }

    // 批量更新为已发布状态
    await prisma.local_services.updateMany({
      where: {
        id: {
          in: expiredServices.map(service => service.id)
        }
      },
      data: {
        status: 'PUBLISHED',
        audit_status: 'APPROVED',
        auto_publish_at: null
      }
    });

    return expiredServices.length;
  }

  /**
   * 搜索所有服务（管理员用）
   * @param {Object} searchParams 搜索参数
   * @returns {Promise<{services: LocalServicePrisma[], total: number}>}
   */
  static async searchAll(searchParams = {}) {
    const {
      category_id = null,
      province = null,
      city = null,
      status = null,
      audit_status = null,
      page = 1,
      limit = 10,
      keyword = null
    } = searchParams;

    const where = {};

    if (category_id) {
      where.category_id = Number(category_id);
    }
    if (province) {
      where.province = province;
    }
    if (city) {
      where.city = city;
    }
    if (status) {
      where.status = status;
    }
    if (audit_status) {
      where.audit_status = audit_status;
    }
    if (keyword) {
      where.OR = [
        { title: { contains: keyword } },
        { basic_services: { contains: keyword } },
        { extended_services: { contains: keyword } }
      ];
    }

    const [services, total] = await Promise.all([
      prisma.local_services.findMany({
        where,
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true,
              phone_number: true
            }
          },
          service_categories: true
        },
        orderBy: { created_at: 'desc' },
        skip: (page - 1) * limit,
        take: limit
      }),
      prisma.local_services.count({ where })
    ]);

    return {
      services: services.map(service => new LocalServicePrisma(service)),
      total
    };
  }

  /**
   * 获取审核统计数据
   * @returns {Promise<Object>} 统计数据
   */
  static async getAuditStats() {
    const [pending, approved, rejected, total] = await Promise.all([
      prisma.local_services.count({
        where: { audit_status: 'PENDING' }
      }),
      prisma.local_services.count({
        where: { audit_status: 'APPROVED' }
      }),
      prisma.local_services.count({
        where: { audit_status: 'REJECTED' }
      }),
      prisma.local_services.count()
    ]);

    return {
      pending,
      approved,
      rejected,
      total
    };
  }

  /**
   * 增加浏览次数
   * @returns {Promise<LocalServicePrisma>}
   */
  async incrementViewCount() {
    const updatedService = await prisma.local_services.update({
      where: { id: BigInt(this.id) },
      data: { view_count: { increment: 1 } }
    });
    this.view_count = updatedService.view_count;
    return this;
  }

  /**
   * 检查用户是否已支付足够保证金
   * @returns {boolean}
   */
  hasEnoughDeposit() {
    return Number(this.deposit_paid) >= Number(this.deposit_required);
  }

  /**
   * 获取解析后的图片数组
   * @returns {Array}
   */
  getParsedImages() {
    if (!this.images) return [];
    try {
      return JSON.parse(this.images);
    } catch (error) {
      return [];
    }
  }

  /**
   * 点赞/取消点赞
   * @param {BigInt} serviceId 服务ID
   * @param {BigInt} userId 用户ID
   * @returns {Promise<{liked: boolean, like_count: number}>}
   */
  static async toggleLike(serviceId, userId) {
    const existingLike = await prisma.local_service_likes.findUnique({
      where: {
        service_id_user_id: {
          service_id: BigInt(serviceId),
          user_id: BigInt(userId)
        }
      }
    });

    if (existingLike) {
      // 取消点赞
      const [, updatedService] = await prisma.$transaction([
        prisma.local_service_likes.delete({
          where: { id: existingLike.id }
        }),
        prisma.local_services.update({
          where: { id: BigInt(serviceId) },
          data: { like_count: { decrement: 1 } }
        })
      ]);
      return { 
        liked: false, 
        like_count: updatedService.like_count 
      };
    } else {
      // 添加点赞
      const [, updatedService] = await prisma.$transaction([
        prisma.local_service_likes.create({
          data: {
            service_id: BigInt(serviceId),
            user_id: BigInt(userId)
          }
        }),
        prisma.local_services.update({
          where: { id: BigInt(serviceId) },
          data: { like_count: { increment: 1 } }
        })
      ]);
      return { 
        liked: true, 
        like_count: updatedService.like_count 
      };
    }
  }

  /**
   * 检查用户是否已点赞
   * @param {BigInt} serviceId 服务ID
   * @param {BigInt} userId 用户ID
   * @returns {Promise<boolean>}
   */
  static async checkUserLiked(serviceId, userId) {
    const like = await prisma.local_service_likes.findUnique({
      where: {
        service_id_user_id: {
          service_id: BigInt(serviceId),
          user_id: BigInt(userId)
        }
      }
    });
    return !!like;
  }

  /**
   * 创建评论
   * @param {Object} data 评论数据
   * @returns {Promise<Object>}
   */
  static async createComment(data) {
    const comment = await prisma.$transaction(async (tx) => {
      const newComment = await tx.local_service_comments.create({
        data: {
          service_id: BigInt(data.service_id),
          user_id: BigInt(data.user_id),
          content: data.content,
        },
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true,
            }
          }
        }
      });

      // 更新服务评论数量
      await tx.local_services.update({
        where: { id: BigInt(data.service_id) },
        data: { comment_count: { increment: 1 } }
      });

      return newComment;
    });

    // 转换BigInt为字符串
    return {
      ...comment,
      id: comment.id.toString(),
      service_id: comment.service_id.toString(),
      user_id: comment.user_id.toString(),
      users: {
        ...comment.users,
        id: comment.users.id.toString()
      }
    };
  }

  /**
   * 获取服务评论列表
   * @param {BigInt} serviceId 服务ID
   * @param {number} page 页码
   * @param {number} pageSize 每页数量
   * @returns {Promise<Object>}
   */
  static async getCommentsByServiceId(serviceId, page = 1, pageSize = 20) {
    const skip = (page - 1) * pageSize;
    
    const [comments, total] = await prisma.$transaction([
      prisma.local_service_comments.findMany({
        where: { service_id: BigInt(serviceId) },
        skip,
        take: pageSize,
        orderBy: {
          created_at: 'asc'
        },
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true,
            }
          }
        }
      }),
      prisma.local_service_comments.count({
        where: { service_id: BigInt(serviceId) }
      })
    ]);

    // 转换BigInt为字符串
    const convertedComments = comments.map(comment => ({
      ...comment,
      id: comment.id.toString(),
      service_id: comment.service_id.toString(),
      user_id: comment.user_id.toString(),
      users: {
        ...comment.users,
        id: comment.users.id.toString()
      }
    }));

    return {
      comments: convertedComments,
      pagination: {
        current_page: page,
        page_size: pageSize,
        total_count: total,
        total_pages: Math.ceil(total / pageSize)
      }
    };
  }

  /**
   * 修复所有服务的计数数据
   * @returns {Promise<{fixed: number, stats: Object}>}
   */
  static async fixAllCounts() {
    const services = await prisma.local_services.findMany({
      select: { id: true }
    });
    
    let fixedCount = 0;
    
    for (const service of services) {
      const [actualLikeCount, actualCommentCount, currentService] = await Promise.all([
        prisma.local_service_likes.count({
          where: { service_id: service.id }
        }),
        prisma.local_service_comments.count({
          where: { service_id: service.id }
        }),
        prisma.local_services.findUnique({
          where: { id: service.id },
          select: { like_count: true, comment_count: true }
        })
      ]);
      
      const needsUpdate = 
        currentService.like_count !== actualLikeCount || 
        currentService.comment_count !== actualCommentCount;
      
      if (needsUpdate) {
        await prisma.local_services.update({
          where: { id: service.id },
          data: {
            like_count: actualLikeCount,
            comment_count: actualCommentCount,
            updated_at: new Date()
          }
        });
        fixedCount++;
      }
    }
    
    // 获取修复后的统计信息
    const [stats, totalLikes, totalComments] = await Promise.all([
      prisma.local_services.aggregate({
        _sum: { like_count: true, comment_count: true },
        _count: { id: true }
      }),
      prisma.local_service_likes.count(),
      prisma.local_service_comments.count()
    ]);
    
    return {
      fixed: fixedCount,
      stats: {
        total_services: stats._count.id,
        stored_likes: stats._sum.like_count,
        actual_likes: totalLikes,
        stored_comments: stats._sum.comment_count,
        actual_comments: totalComments,
        is_consistent: stats._sum.like_count === totalLikes && stats._sum.comment_count === totalComments
      }
    };
  }

  /**
   * 获取数据一致性报告
   * @returns {Promise<Object>}
   */
  static async getConsistencyReport() {
    const [storedStats, actualLikes, actualComments] = await Promise.all([
      prisma.local_services.aggregate({
        _sum: { like_count: true, comment_count: true },
        _count: { id: true }
      }),
      prisma.local_service_likes.count(),
      prisma.local_service_comments.count()
    ]);
    
    // 查找不一致的服务
    const inconsistentServices = await prisma.$queryRaw`
      SELECT 
        ls.id,
        ls.title,
        ls.like_count as stored_likes,
        ls.comment_count as stored_comments,
        COALESCE(like_stats.actual_likes, 0) as actual_likes,
        COALESCE(comment_stats.actual_comments, 0) as actual_comments
      FROM local_services ls
      LEFT JOIN (
        SELECT service_id, COUNT(*) as actual_likes
        FROM local_service_likes
        GROUP BY service_id
      ) like_stats ON ls.id = like_stats.service_id
      LEFT JOIN (
        SELECT service_id, COUNT(*) as actual_comments
        FROM local_service_comments
        GROUP BY service_id
      ) comment_stats ON ls.id = comment_stats.service_id
      WHERE 
        ls.like_count != COALESCE(like_stats.actual_likes, 0)
        OR ls.comment_count != COALESCE(comment_stats.actual_comments, 0)
      LIMIT 20
    `;
    
    return {
      summary: {
        total_services: storedStats._count.id,
        stored_likes: storedStats._sum.like_count,
        actual_likes: actualLikes,
        stored_comments: storedStats._sum.comment_count,
        actual_comments: actualComments,
        likes_consistent: storedStats._sum.like_count === actualLikes,
        comments_consistent: storedStats._sum.comment_count === actualComments,
        inconsistent_services_count: inconsistentServices.length
      },
      inconsistent_services: inconsistentServices.map(service => ({
        ...service,
        id: service.id.toString()
      }))
    };
  }

  /**
   * 序列化为普通对象
   * @returns {Object}
   */
  toJSON() {
    const result = {
      id: this.id?.toString(),
      user_id: this.user_id?.toString(),
      category_id: this.category_id,
      title: this.title,
      province: this.province,
      city: this.city,
      basic_services: this.basic_services,
      extended_services: this.extended_services,
      after_sale_service: this.after_sale_service,
      contact_info: this.contact_info,
      images: this.getParsedImages(),
      status: this.status,
      audit_status: this.audit_status,
      audit_comment: this.audit_comment,
      audit_time: this.audit_time,
      auto_publish_at: this.auto_publish_at,
      deposit_required: Number(this.deposit_required),
      deposit_paid: Number(this.deposit_paid),
      view_count: this.view_count,
      like_count: this.like_count || 0,
      comment_count: this.comment_count || 0,
      created_at: this.created_at,
      updated_at: this.updated_at
    };

    // 处理user关联对象，确保BigInt字段被转换为字符串
    if (this.user) {
      result.user = {
        ...this.user,
        id: this.user.id?.toString(),
        inviter_id: this.user.inviter_id?.toString()
      };
    }

    // 处理category关联对象
    if (this.category) {
      result.category = {
        ...this.category
      };
    }

    return result;
  }
}

module.exports = LocalServicePrisma;